from util.DLT698 import *
from util.Encoder import*
# import support
from dateutil.relativedelta import relativedelta
from util.MeterDoc import* 
# from src.detection.const import ENotifyTypeUI
from random import randint
# from util.common_huayun import StepLogAndPrint
# from util.support import Support
# import util.support
import util.tool as tool
from util.protocol_dx import *
import select
import binascii
class LogOption:
    mess = ""
    Is_qualified = 1
    def __init__(self, exec_notify) -> None:
        self.exec_notify = exec_notify
    def append_step(self, msg,IS_Qualified=1):
        if IS_Qualified == 0:
            self.Is_qualified = 0
        tim = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        self.mess += "\n" + tim + " " + msg
        print(tim + " " + msg)
        print("____________________________")
        # self.exec_notify(ENotifyTypeUI.NOTIFY_LOG, msg, True)

    def print_step(self):
        mes_list = self.mess.split("\n")
        le = len(mes_list)
        if le:
            print(mes_list[le - 1])
class GeneralProcedure(LogOption):
    meterAddrs = ["000000000001","000000000002","000000000003"]
    wait_tm = 0
    record_num = 0
    dic_record = {}
    block_time = []
    time_initial = datetime.datetime.now()
    def __init__(self,client_socket, y_esam_no, energy_unit, address, exec_notify,full_fra = 0):
        super().__init__(exec_notify)
        self.client_socket=client_socket
        self.y_esam_no = y_esam_no
        self.energy_unit = energy_unit
        self.address = address
        self.exec_notify = exec_notify
        #整帧报文
        self.full_fra = full_fra

    """
    下发档案
    """
    
    def get_set_meter_docs_apdu(self, is_return = 0):
        docs = []
        mes_op = "下发档案"
        for i,addr in enumerate(self.meterAddrs):
            #cfgNum = DT_UInt16(i)
            Basic_obj = Make_A_MeterDoc_Basic_obj(addr,3,3,"F2010201","000000000000",4,i,3,2200,15)
            Extended_obj = Make_A_MeterDoc_Extended_obj("000000000000", "000000000000",1,1)
            Annex_obj = Make_A_MeterDoc_Annex_obj()

            meterDoc = Make_A_MeterDoc(i + 1, Basic_obj, Extended_obj, Annex_obj)
            docs.append(meterDoc)

        datas =  Make_MeterDoc_Array(docs)
        frame_send = GetApdu("000000000006", False, datas)
        if is_return:
            return frame_send
        self.Send_fr(frame_send, mes_op)
    """
    发送报文
    frame_send: 需要发送的报文
    mes_op: 步骤信息，方便log打印
    is_return: 是否需要返回值，返回结果apdu，默认无需返回值（=0），如果只是判断是否发送、设置成功无需返回值
    """
    def Send_fr(self, frame_send:str, mes_op:str="", is_return = 0):
        if mes_op:
            self.append_step(mes_op)
        if frame_send == None:
            return ""
        prt = Protocol_Dx()
        sendf = prt.set_address(getTerAddr("000000000003")).set_address_type("0").set_link_user_data(frame_send).format_frame_string()
        self.append_step("发送报文: " + tool.add_spaces_every_two_chars(sendf))
        frame_send = prt.parser_frame(sendf).get_link_user_data()
        data = binascii.unhexlify(sendf)
        self.client_socket.send(data)
        while True:
            # data = self.client_socket.recv(1024)
            data=self.receive_with_timeout(self.client_socket)
            if data == "":
                return data
            hex_data = binascii.hexlify(data).decode('ascii')
            print("接收的报文:{}".format(hex_data))
            apdu=tool.dedcode(hex_data)["apdu"]
            if apdu[:2]=="01":
                fra_send=self.LINK_Response(apdu)
                self.client_socket.send(fra_send)
                continue
            else:
                if not is_return:
                    dar = ServiceJudgment(apdu)
                    if dar[1] == "00":
                        self.append_step(mes_op + " 成功")
                        return True
                    else:
                        self.append_step(mes_op + " 失败")
                        self.Is_qualified = 0
                        return False
                else:
                    self.append_step("回复apdu：" + apdu)
                    return apdu
    def receive_with_timeout(self,client_socket,timeout=10,net=1):
        ready_to_read, _, _ = select.select([client_socket], [], [], timeout)
        if ready_to_read:  # 如果socket在指定时间内有数据可读
            data = client_socket.recv(2048)
            return data
        else:  # 超时
            if net:
                self.append_step("Receive timeout")
            return ""
    def Send_fr1(self, frame_send:str, mes_op:str="", is_return = 0):
        if mes_op:
            self.append_step(mes_op)
        if frame_send == None:
            return ""
          
        if self.full_fra:
            prt = Protocol_Dx()
            sendf = prt.set_address(getTerAddr("000000000003")).set_address_type("0").set_link_user_data(frame_send).format_frame_string()
            self.append_step("发送报文: " + tool.add_spaces_every_two_chars(sendf))
            frame_send = prt.parser_frame(sendf).get_link_user_data()
            ###发送报文
            # result = support.safe_not_trance_698(sendf, self.y_esam_no, self.energy_unit, self.address, self.exec_notify)
        else:                         
            self.append_step("发送APDU: " + tool.add_spaces_every_two_chars(frame_send))
            # result = support.safe_trance_698(frame_send, self.y_esam_no, self.energy_unit, self.address, self.exec_notify)
        result = [0, "86 01 02 4F FF 05 02 00 06 00 ","hao"]

        if not result:  
            return ""   
        if result[0]:
            self.append_step(mes_op + " 请求失败",0)
            self.append_step("错误信息：" + result[2],0)
            return False
        else:
            if not is_return:
                dar = ServiceJudgment(result[1])
                if dar[1] == "00":
                    self.append_step(mes_op + " 成功")
                    return True
                else:
                    self.append_step(mes_op + " 失败",0)
                    return False
            else:
                self.append_step("回复apdu：" + result[1])
                return result[1] 

    def init_para(self):
        self.block_time = []
        self.dic_record = {}
        self.record_num = 0
    def init_qualified(self):
        self.Is_qualified = 1
    """
    获取当前时间
    """
    def get_time(self, day, start="", end="", is_16 = 0, full_time = 0, last = 0, m = 0):
        temp_date = datetime.datetime.now() 
        if last:
            return En_DateTimeS((temp_date + datetime.timedelta(minutes=m)).strftime("%Y%m%d%H%M%S"))
        if full_time:
            if is_16:
                return En_DateTimeS((temp_date + datetime.timedelta(days =+ day)).strftime("%Y%m%d%H%M%S"))
            else:
                begin_t = (temp_date + datetime.timedelta(days =+ day)).strftime("%Y%m%d%H%M%S")
        else:
            begin_t = (temp_date + datetime.timedelta(days =+ day)).strftime("%Y%m%d")+start
            end_t= (temp_date + datetime.timedelta(days =+ day)).strftime("%Y%m%d")+end
        match is_16:
            case 1:
                return En_DateTimeS(begin_t)
            case 2:
                return begin_t
        return begin_t, end_t
    
    """数据初始化"""
    def DataInit(self):
        mes_op = "数据区初始化"
        oad = "43 00 03 00"
        data = "00"
        frame_send = GetServerJudgment(oad, 7, data)
        self.Send_fr(frame_send, mes_op)
        self.delay(120)
        
    """建立连接"""
    def EstablishAppConn(self, tResult):
        self.append_step("建立应用连接，采用数字签名的认证机制")
        result = support.enc_negotiate("", self.energy_unit, self.exec_notify)
        if result.ret != 0:
            return False
        self.session_data = result.get_data()
        self.y_esam_no = self.session_data.get_y_esam_no()
        self.address = self.session_data.get_device_address()
        self.stepLogAndPrint = StepLogAndPrint(exec_notify)
        return True
        

    """
    终端校时
    day: 校时天数
    HMS：校时到的时分秒 格式：235959（23：59：59）
    is_month_end：是否是月末的时间设置
    last_month: 1 将至于大上个月末
    """
    def TerminalCalibration(self, day:int, HMS="", is_month_end = 0, this_month = 0, last_month = 0,now=0, RELEASE = 0):
        HMS = str(HMS).replace(":","").replace(" ","")
        # if not is_month_end:
        #     mes_op = "终端校时"
        oad = "40000200"
        data = "1C"
        temp_date = datetime.datetime.now() 
        if is_month_end:
            date = (temp_date - relativedelta(days=temp_date.day - day) + relativedelta(months = 1)).strftime("%Y%m%d")+HMS
            mes_op = "终端校时:"+ (temp_date - relativedelta(days=temp_date.day - day) + relativedelta(months = 1)).strftime("%Y-%m-%d ")+HMS[:2] + ":" + HMS[2:4] + ":" + HMS[4:]
        elif this_month:
            date = temp_date.strftime("%Y%m")+HMS
        elif last_month:
            date = (temp_date - relativedelta(days=temp_date.day - day) + relativedelta(months = -1)).strftime("%Y%m%d")+HMS
            mes_op = "终端校时:"+ (temp_date - relativedelta(days=temp_date.day - day) + relativedelta(months = -1)).strftime("%Y-%m-%d ")+HMS[:2] + ":" + HMS[2:4] + ":" + HMS[4:]
        elif now:
            date = (temp_date + datetime.timedelta(days =+ day)).strftime("%Y%m%d%H%M%S")
            mes_op = "终端校时:"+ (temp_date + datetime.timedelta(days =+ day)).strftime("%Y-%m-%d %H:%M:%S")
        else:
            date = (temp_date + datetime.timedelta(days =+ day)).strftime("%Y%m%d")+HMS
            mes_op = "终端校时:"+ (temp_date + datetime.timedelta(days =+ day)).strftime("%Y-%m-%d ")+HMS[:2] + ":" + HMS[2:4] + ":" + HMS[4:]
        data_16 = En_DateTimeS(date)
        data += data_16
        frame_send = SetRequestNormal(oad,data)
        if RELEASE == 0:
            self.Send_fr(frame_send, mes_op)
        else:
            apdu = self.Send_fr(frame_send, mes_op,1)
            if apdu!="":
                dar = ServiceJudgment(apdu)
                if dar == "00":
                    self.append_step("响应错误,不应设置成功 不合格")
                    self.Is_qualified = 0
            else:
                self.append_step("响应错误 不合格")
                self.Is_qualified = 0

    """
    终端延时
    tm：延时多少秒
    """
    def delay1(self, tm):
        mes_op = "延时等待{} s".format(tm)
        self.append_step(mes_op)
        time.sleep(tm)
        mes_op = "延时结束"
        self.append_step(mes_op)
    def delay(self,tm):
        mes_op = "延时等待{} s".format(tm)
        self.append_step(mes_op)
        t=time.time()
        while time.time()-t<tm:
            data=self.receive_with_timeout(self.client_socket,net=0)
            hex_data = binascii.hexlify(data).decode('ascii')
            apdu=tool.dedcode(hex_data)["apdu"]
            if apdu[:2]=="01":
                fra_send=self.LINK_Response(apdu)
                self.client_socket.send(fra_send)
                continue
        mes_op = "延时结束"
        self.append_step(mes_op)
    """清空操作"""
    def ClearOpt(self, mes_op):
        mes_op = mes_op.replace(" ","") 
        dic = {
            "清空采集任务配置表": "60128100",
            "清空事件采集方案"  : "60168100",
            "清空普通采集方案"  : "60148100",
            "清空上报方案"     : "601C8100",
            "清空采集档案配置表" : "60008600"
        }
        oad = dic[mes_op]
        data = "00"
        frame_send = GetServerJudgment(oad, 7, data)
        return self.Send_fr(frame_send, mes_op)


    """设置事件有效标志(310A0900)；"""
    def SetEventValidFlagValid(self, is_valid = 1):
        
        oad = "31 14 09 00"
        if is_valid:
            data = "0301"
            mes_op = "设置事件有效标志为 有效"
        else:
            data = "0300"
            mes_op = "设置事件有效标志为 无效"
        frame_send = GetServerJudgment(oad, 6 ,data)
        
        return self.Send_fr(frame_send, mes_op)

    """
    终端主动上报设置
    button：（默认）0 禁止终端主动上报
                   1 允许终端主动上报
    """
    def TerminalsReportingProactively(self, button = 0):
        if not button:
            mes_op = "禁止终端主动上报"
            data = "0300"
        else:
            mes_op = "允许终端主动上报"
            data = "0301"
        oad = "43000800"
        frame_send = GetServerJudgment(oad, 6, data)
        return self.Send_fr(frame_send, mes_op)
    # """
    # 装饰器：等待上报
    # """
    # def WaitReport(self, fuc):
    #     def ReportProcessing():
    #         tim = time.time()
    #         GeneralProcedure.wait_tm = 1
    #         while GeneralProcedure.wait_tm > time.time() - tim:
    #             result = ""
    #             fuc()

    #     return ReportProcessing
    # def EventTable
    def ReadEventRecord(self):
        record_oad = {'读取事件记录_电能表失压事件': '00060003', '读取事件记录_电能表欠压事件': '01060003', '读取事件记录_电能表过压事件': '02060003', '读取事件记录_电能表断相事件': '03060003', '读取事件记录_电能表失流事件': '04060003', '读取事件记录_电能表过流事件': '05060003', '读取事件记录_电能表断流事件': '06060003', '读取事件记录_电能表潮流反向事件': '07060003', '读取事件记录_电能表过载事件': '08060003', '读取事件记录_电能表正向有功需量超限事件': '09020003', '读取事件记录_电能表反向有功需量超限事件': '0A020003', '读取事件记录_电能表无功需量超限事件': '0B060003', '读取事件记录_电能表功率因数超下限事件': '0C020003', '读取事件记录_电能表全失压事件': '0D020003', '读取事件记录_电能表辅助电源掉电事件': '0E020003', '读取事件记录_电能表电压逆相序事件': '0F020003', '读取事件记录_电能表电流逆相序事件': '10020003', '读取事件记录_电能表掉电事件': '11020003', '读取事件记录_电能表编程事件': '12020003', '读取事件记录_电能表清零事件': '13020003', '读取事件记录_电能表需量清零事件': '14020003', '读取事件记录_电能表事件清零事件': '15020003', '读取事件记录_电能表校时事件': '16020003', '读取事件记录_电能表时段表编程事件': '17020003', '读取事件记录_电能表时区表编程事件': '18020003', '读取事件记录_电能表周休日编程事件': '19020003', '读取事件记录_电能表结算日编程事件': '1A020003', '读取事件记录_电能表开盖事件': '1B020003', '读取事件记录_电能表开端钮盒事件': '1C020003', '读取事件记录_电能表电压不平衡事件': '1D020003', '读取事件记录_电能表电流不平衡事件': '1E020003', '读取事件记录_电能表跳闸事件': '1F020003', '读取事件记录_电能表合闸事件': '20020003', '读取事件记录_电能表节假日编程事件': '21020003', '读取事件记录_电能表有功组合方式编程事件': '22020003', '读取事件记录_电能表无功组合方式编程事件': '23020003', '读取事件记录_电能表费率参数表编程事件': '24020003', '读取事件记录_电能表阶梯表编程事件': '25020003', '读取事件记录_电能表密钥更新事件': '26020003', '读取事件记录_电能表异常插卡事件': '27020003', '读取事件记录_电能表购电记录': '28020003', '读取事件记录_电能表退费记录': '29020003', '读取事件记录_电能表恒定磁场干扰事件': '2A020003', '读取事件记录_电能表负荷开关误动作事件': '2B020003', '读取事件记录_电能表电源异常事件': '2C020003', '读取事件记录_电能表电流严重不平衡事件': '2D020003', '读取事件记录_电能表时钟故障事件': '2E020003', '读取事件记录_电能表计量芯片故障事件': '2F020003'}
        temp_date = self.get_time(0,"",is_16=2)
        start_t = self.get_time(0,"000000",is_16=1)
        end_t = self .get_time(0,"235959",is_16=1)
        for key,val in record_oad.items():
            
            # frame_send = "05 03 04 60 12 03 00 07 {} {} 00 00 00 01 02 00 20 2A 02 00 01 30 {} 06 00 03 20 22 02 00 20 1E 02 00 20 20 02 00 00".format(start_time,end_time,val)
            frame_send = "05 03 09 60 12 03 00 07 {} {} 00 00 00 01 02 00 20 2A 02 00 01 30 {} 20 22 02 00 20 1E 02 00 20 20 02 00".format(start_t,end_t,val)
            apdu = self.Send_fr(frame_send, key, 1)
            _, rcsd, dar, A_RecordRowStrList, dataStr=ServiceJudgment(apdu)
            if dar =="":
                
                begin,_,_ = Get_Column_Val_From_A_ResultRecord(dataStr,"201E0200")
                end,_,_ = Get_Column_Val_From_A_ResultRecord(dataStr,"201E0200")
                if len(begin) == 3 and len(end) == 3:
                    for i  in begin:
                        if (i[28])[:8] != temp_date:
                            self.append_step("error：" + key + " 错误")
                            self.Is_qualified = 0
                    for j in end:
                        if (j[28])[:8] != temp_date:
                            self.append_step("error：" + key + " 错误")
                            self.Is_qualified = 0
                # _, csds, _ = De_RCSD(rcsd)
                # col = len(csds)
                # for row in A_RecordRowStrList:
                #     _, datas, _ = De_A_RecordRow(row, col)
                #     data = De_Data(datas[1])
                #     data = data[3]
                #     start_time = list(data[1].values())[0]
                #     end_time = list(data[2].values())[0]
                #     if data and len(data.keys()) == 3 and start_time[:8] == end_time[:8] == temp_date:
                #         self.append_step(key + " 正确")
                #     else:
                #         self.append_step("error：" + key + " 错误")
                #         self.Is_qualified = 0
            else:
                self.append_step("erro：返回错误码：{} 不合格".format(dar))
                self.Is_qualified = 0

    """
    上报处理
    apdu:上报apdu
    OAD：需要的上报OAD
    is_record：是否回复确认帧
    """
    ###处理
    def ReportProgram(self, oad, is_record = 1, methed = 0, begin_time = "", end_time = ""):
        # try:
        GeneralProcedure.wait_tm = 1
        self.append_step("延时{}s，等待终端上报".format(GeneralProcedure.wait_tm))
        # while GeneralProcedure.wait_tm > time.time() - tim:
        ###接收上报
        oads, A_ResultRecord_Str_List, piid = ServiceJudgment(apdu)
        for i in A_ResultRecord_Str_List:
            # lens, oad, rcsd, dar, A_RecordRowStrList, dataStr = De_A_ResultRecord(i)
            for j in oads:
                if j in oad:
                    if j in self.dic_record.keys():
                        self.dic_record[j] += 1
                    else:
                        self.dic_record[j] = 1
                match methed:
                    case 1:
                        self.record_19(j, i, begin_time, end_time)
                    case 2:
                        self.record_31(j, i, begin_time, end_time)
                        # _, csds, rcsd_str = De_RCSD(rcsd)
                        # col = len(csds)
                        # for row in A_RecordRowStrList:
                        #     lens, datas, dataStr = De_A_RecordRow(row, col)
                        #     for j in datas:
                        #         data_dic = De_Data(j)
                        #         print(data_dic)
    
        if is_record:
            self.RecordComfirFra(apdu, oads)
        else:
            self.append_step("不回复确认帧")
        
        match methed:
            case 1:
                for i in oads:
                    if i=="60120300":
                        if self.record_num != 36:
                            self.append_step("erro：上报数据点数：{} 不合格".format(self.record_num))
                            self.Is_qualified = 0
                        else:
                            self.append_step("上报数据点数：{} ".format(self.record_num))
            case 2:
                if self.record_num == 12:
                     self.append_step("上报数：{} 正确".format(self.record_num))
                else:
                    self.append_step("erro：上报数：{} 不足 不合格".format(self.record_num))
                    self.Is_qualified = 0

        if not is_record:
            self.NoRecord(oad)
        # except:
        #     self.append_step("erro：上报报文异常 不合格")
        #     self.Is_qualified = 0
    def Judg(self,x,y,meg):
        if x == y:
            self.append_step(meg+"响应 正确")
        else:
            self.append_step(meg+"响应错误 不合格")
            self.Is_qualified = 0
    def Judg(self,x,meg):
        if x:
            self.append_step(meg+"响应 正确")
        else:
            self.append_step(meg+"响应错误 不合格")
            self.Is_qualified = 0
    def record_19(self, oad, A_ResultRecord_Str, end_time, begin_time):
        #15m 3h 3meter
        if oad == "60120300":
            colVals,_,_ = Get_Column_Val_From_A_ResultRecord(A_ResultRecord_Str,"20210200")
            re_num = len(colVals)
            self.record_num += re_num
            self.append_step("本次上报数据点数：{} ".format(re_num))
            self.append_step("累计上报数据点数：{} ".format(self.record_num))
            for i in colVals:
                date = i[28]
                if int(date) < int(end_time) and int(date)>= int(begin_time):
                    if date in self.block_time:
                        self.append_step("冻结时间 {} 异常 不合格".format(date),0)
                    else:
                        self.block_time.append(i[28])
                else:
                    self.append_step("冻结时间 {} 异常 不合格".format(date),0)
        elif oad =="40000200":
            if not len(A_ResultRecord_Str):
                self.append_step("oad:{} 上报异常 不合格".format(oad),0)
    def record_31(self, oad, A_ResultRecord_Str,begin_time,end_time ):
        if oad == "60120300":
            self.record_num += 1
            self.append_step("终端上报，上报次数 [ {} ] ".format(self.record_num))
            colVals,_,_ = Get_Column_Val_From_A_ResultRecord(A_ResultRecord_Str,"201E0200")
            for i in colVals:
                date = i[28]
                if int(date) >= int(end_time) and int(date) < int(begin_time):
                    self.append_step("error: 时间 {} 异常 不合格".format(date),0)

    def NoRecord(self, oad):
        if not self.dic_record:
            self.append_step("erro：未收到正确的上报信息 不合格",0)
            return
        for key, value in self.dic_record.items():
            if value != 3:
                self.append_step("erro：({}) 不回复确认帧 应重复上报3次 实则上报{}次 不合格".format(key, value),0)
            else:
                self.append_step("不回复确认帧 重复上报3次 合格")
        if len(self.dic_record.keys())!=len(oad):
            self.append_step("erro：上报数据不足 不合格",0)
    def Rec_record(self, meg,apdu,butt,report=0):
        self.wait_tm = 30
        tim = time.time()
        piid = -1
        while self.wait_tm < time.time() - tim:
            ###上报 
            if report:
                match butt:
                    case 1:
                        pass
            else:
                next_piid = tool.str2int(apdu[2:4])
                match butt:
                    case 3:
                        if piid == 63 and next_piid != 0:
                            self.append_step(meg+"上报响应错误 不合格",0)
                            break  
                        if piid+1 == next_piid and next_piid <= 63:
                            piid += 1
                            oads, _, _ = ServiceJudgment(apdu)
                            self.RecordComfirFra(apdu, oads)
                            continue
                        else:
                            self.append_step(meg+"上报响应错误 不合格",0)
                            break  
                    case 4:
                        if piid == -1:
                            piid = next_piid
                        elif piid == next_piid:
                            self.append_step(meg+"上报响应piid回复正确 合格")
                        else:
                            self.append_step(meg+"上报响应错误 不合格",0)
                            break 
    def RecordComfirFra(self, apdu, oads):
        server = apdu[2:4]
        piid = apdu[4:6]
        confir_apdu = ReportComfir(server, piid, oads)
        return self.Send_fr(confir_apdu, "上报回复确认帧")
        
    def ReadTerminalClockEvent(self):
        mes_op = "读取终端对时事件"
        frame_send = "05 03 01 31 14 02 00 09 01 03 00 20 22 02 00 00 20 1E 02 00 00 20 20 02 00 00 "
        apdu = self.Send_fr(frame_send, mes_op, 1)
        _, _, dar, A_RecordRowStrList, _ = ServiceJudgment(apdu)
        if dar!="00":
            num = len(A_RecordRowStrList)
            if num == 1:
                self.append_step("终端对时事件数量{}，正确".format(num))
            else:
                self.append_step("error：终端对时事件数量{}，错误".format(num),0)
        else:
            self.append_step("erro：返回错误码：{} 不合格".format(dar),0)
    def ReadTerminalErrorRecord(self, method = 0):
        mes_op = "读取终端故障记录"
        frame_send = "05 03 10 31 0A 02 00 09 01 03 00 20 22 02 00 00 20 1E 02 00 00 20 20 02 00 00"
        apdu = self.Send_fr(frame_send, mes_op, is_return=1)
        _, rcsd, dar, A_RecordRowStrList, dataStr=ServiceJudgment(apdu)
        
        if dar!="00":
            match method:
                case 1:
                
                    if len(A_RecordRowStrList) == 1:
                        self.append_step("读取终端故障记录数量为{}，正确".format(1))
                        begin_time,_,_ = Get_Column_Val_From_A_ResultRecord(dataStr,"201E0200")
                        end_time,_,_ = Get_Column_Val_From_A_ResultRecord(dataStr,"20200200")
                        try:
                            if len(begin_time[0]) and end_time[0] == "NULL":
                                self.append_step("读取终端故障记录时间正确")
                            else:
                                self.append_step("error：读取终端故障记录时间错误",0)
                                return False
                        except Exception as r:
                            print("%s"%r)
                            return False
                    else:
                        self.append_step("error：终端故障记录数量为{}，错误，应为{}".format( len(A_RecordRowStrList),1),0)
                        return False
                case 2:
                    if len(A_RecordRowStrList) == 1:
                        self.append_step("终端故障记录数量为{}，正确".format(1))
                    else:
                        self.append_step("error：终端故障记录数量为{}，错误，应为{}".format( len(A_RecordRowStrList),1),0)
                        return False
                case 3:
                    if len(A_RecordRowStrList) == 2:
                        self.append_step("终端故障记录数量为{}，正确".format(2))
                        end_time,_,_ = Get_Column_Val_From_A_ResultRecord(dataStr,"20200200")
                        date = self.get_time(0, start="001", is_16=2)
                        try:
                            if (end_time[1])[:11] == date:
                                self.append_step("终端故障记录结束时间 合理")
                            else:
                                self.append_step("error：终端故障记录结束时间 不合理",0)
                                return False
                        except Exception as r:
                            print("%s"%r)
                            return False
                    else:
                        self.append_step("error：终端故障记录数量为{}，错误，应为{}".format( len(A_RecordRowStrList),2),0)
                        return False
                case 4:
                    if len(A_RecordRowStrList) == 0:
                        self.append_step("终端故障记录数量为{}，正确".format(0))
                    else:
                        self.append_step("error：终端故障记录数量为{}，错误，应为{}".format( len(A_RecordRowStrList),0),0)
                        return False
               
        else:
            self.append_step("erro：返回错误码：{} 不合格".format(dar),0)
            self.Is_qualified = 0
            return False
        return True
    def SendCollPlan_31(self):
        record_list = ["00"]*12
        index = randint(0, len(record_list)-1)
        record_list[index] = "01"
        # 15）	下装事件采集方案1(60167F00)，采集的数据内容为(30000600 30010600 30020600 30030600 ，电表集合为全部电表；
        frame_send = "07 01 2a 60 16 7f 00 01 01 02 05 11 01 02 02 11 00 01 04 52 30 00 06 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 01 06 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 02 06 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 03 06 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 5c 01 03 {} 12 01 00 00".format(record_list[0])
        info = self.Send_fr(frame_send, "下装事件采集方案 1 ")
        if info == "" or info == False:
            return False
        # 16）	下装事件采集方案2(60167F00)，采集的数据内容为(30040600 30050600 30060600 30070600 ，电表集合为全部电表；
        frame_send = "07 01 2b 60 16 7f 00 01 01 02 05 11 02 02 02 11 00 01 04 52 30 04 06 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 05 06 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 06 06 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 07 06 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 5c 01 03 {} 12 01 00 00".format(record_list[1])
        info = self.Send_fr(frame_send, "下装事件采集方案 2 ")
        if info == "" or info == False:
            return False
        # 17）	下装事件采集方案3(60167F00)，采集的数据内容为(30080600 30090200 300A0200 300B0600，电表集合为全部电表；
        frame_send = "07 01 2c 60 16 7f 00 01 01 02 05 11 03 02 02 11 00 01 04 52 30 08 06 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 09 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 0a 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 0b 06 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 5c 01 03 {} 12 01 00 00".format(record_list[2])
        info = self.Send_fr(frame_send, "下装事件采集方案 3 ")
        if info == "" or info == False:
            return False
        # 18）	下装事件采集方案4(60167F00)，采集的数据内容为(300C0200 300D0200 300E0200 300F0200，电表集合为全部电表；
        frame_send = "07 01 2d 60 16 7f 00 01 01 02 05 11 04 02 02 11 00 01 04 52 30 0c 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 0d 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 0e 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 0f 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 5c 01 03 {} 12 01 00 00".format(record_list[3])
        info = self.Send_fr(frame_send, "下装事件采集方案 4 ")
        if info == "" or info == False:
            return False
        # 19）	下装事件采集方案5(60167F00)，采集的数据内容为(30100200 30110200 30120200 30130200，电表集合为全部电表；
        frame_send = "07 01 2e 60 16 7f 00 01 01 02 05 11 05 02 02 11 00 01 04 52 30 10 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 11 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 12 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 13 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 5c 01 03 {} 12 01 00 00".format(record_list[4])
        info = self.Send_fr(frame_send, "下装事件采集方案 5 ")
        if info == "" or info == False:
            return False
        # 20）	下装事件采集方案6(60167F00)，采集的数据内容为(30140200 30150200 30160200 30170200，电表集合为全部电表；
        frame_send = "07 01 2f 60 16 7f 00 01 01 02 05 11 06 02 02 11 00 01 04 52 30 14 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 15 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 16 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 17 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 5c 01 03 {} 12 01 00 00".format(record_list[5])
        info = self.Send_fr(frame_send, "下装事件采集方案 6 ")
        if info == "" or info == False:
            return False
        # 21）	下装事件采集方案7(60167F00)，采集的数据内容为(30180200 30190200 301A0200 301B0200，电表集合为全部电表；
        frame_send = "07 01 30 60 16 7f 00 01 01 02 05 11 07 02 02 11 00 01 04 52 30 18 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 19 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 1a 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 1b 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 5c 01 03 {} 12 01 00 00".format(record_list[6])
        info = self.Send_fr(frame_send, "下装事件采集方案 7 ")
        if info == "" or info == False:
            return False
        # 22）	下装事件采集方案8(60167F00)，采集的数据内容为(301C0200 301D0200 301E0200 301F0200，电表集合为全部电表；
        frame_send = "07 01 31 60 16 7f 00 01 01 02 05 11 08 02 02 11 00 01 04 52 30 1c 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 1d 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 1e 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 1f 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 5c 01 03 {} 12 01 00 00".format(record_list[7])
        info = self.Send_fr(frame_send, "下装事件采集方案 8 ")
        if info == "" or info == False:
            return False
        # 23）	下装事件采集方案9(60167F00)，采集的数据内容为(30200200 30210200 30220200 30230200，电表集合为全部电表；
        frame_send = "07 01 32 60 16 7f 00 01 01 02 05 11 09 02 02 11 00 01 04 52 30 20 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 21 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 22 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 23 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 5c 01 03 {} 12 01 00 00".format(record_list[8])
        info = self.Send_fr(frame_send, "下装事件采集方案 9 ")
        if info == "" or info == False:
            return False
        # 24）	下装事件采集方案10(60167F00)，采集的数据内容为(30240200 30250200 30260200 30270200，电表集合为全部电表；
        frame_send = "07 01 33 60 16 7f 00 01 01 02 05 11 0a 02 02 11 00 01 04 52 30 24 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 25 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 26 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 27 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 5c 01 03 {} 12 01 00 00".format(record_list[9])
        info = self.Send_fr(frame_send, "下装事件采集方案 10 ")
        if info == "" or info == False:
            return False
        # 25）	下装事件采集方案11(60167F00)，采集的数据内容为(30280200 30290200 302A0200 302B0200，电表集合为全部电表；
        frame_send = "07 01 34 60 16 7f 00 01 01 02 05 11 0b 02 02 11 00 01 04 52 30 28 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 29 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 2a 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 2b 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 5c 01 03 {} 12 01 00 00".format(record_list[10])
        info = self.Send_fr(frame_send, "下装事件采集方案 11 ")
        if info == "" or info == False:
            return False
        # 26）	下装事件采集方案12(60167F00)，采集的数据内容为(302C0200 302D0200 302E0200 302F0200)，电表集合为全部电表；
        frame_send = "07 01 35 60 16 7f 00 01 01 02 05 11 0c 02 02 11 00 01 04 52 30 2c 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 2d 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 2e 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 52 30 2f 02 00 03 20 22 02 00 20 1e 02 00 20 20 02 00 5c 01 03 {} 12 01 00 00".format(record_list[11])
        info = self.Send_fr(frame_send, "下装事件采集方案 12 ")
        if info == "" or info == False:
            return False
# 
        for i in range(1, 13):
            lab = hex(i).replace("x","")
            frame_send = "07 01 36 60 12 7F 00 01 01 02 0C 11 {} 54 01 00 0A 16 02 11 {} 1C 07 E8 01 1C 00 00 00 1C 08 33 09 09 09 09 09 54 01 00 00 11 02 16 01 12 00 00 12 00 00 02 02 16 00 01 01 02 04 11 00 11 00 11 17 11 3B 00".format(lab, lab)
            info = self.Send_fr(frame_send, "下装采集任务{} ".format(i))
            if info == "" or info == False:
                return False
    # def SetRecordPort_19(self):
    #     oad = "43 00 0A 00 "
    #     data = "01 01 51 45 10 00 00"
    #     frame_send = SetRequestNormal(oad, data)
    #     self.Send_fr(frame_send, "设置上报通道")
    def SetRecordPort(self):
        mes_op = "设置上报通道"
        oad = "43 00 0A 00 "
        data = "01 01 51 45 10 00 00"
        frame_send = SetRequestNormal(oad, data)
        self.Send_fr(frame_send, mes_op)
    
    """读取终端抄表失败事件记录"""
    def ReadTerminalErrorEventRecord(self,method=0):
        frame_send = "05 03 0E 31 0F 02 00 09 01 03 00 20 22 02 00 00 20 1E 02 00 00 20 20 02 00 00 "
        apdu = self.Send_fr(frame_send, "读取终端抄表失败事件记录", 1)
        _, _, dar, A_RecordRowStrList, dataStr=ServiceJudgment(apdu)
        if dar!="00":
            num = len(A_RecordRowStrList)
            match method:
                case 1:
                    if num == 0:
                        self.append_step("终端抄表失败事件记录数量为{}，正确".format(num))
                    else:
                        self.append_step("error：终端抄表失败事件记录数量为{}，错误，应为 0".format(num),0)
                    
                case 2:
                    if num == 1:
                        self.append_step("终端抄表失败事件记录数量为{}，正确".format(num))
                        begin_time,_,_ = Get_Column_Val_From_A_ResultRecord(dataStr,"201E0200")
                        end_time,_,_ = Get_Column_Val_From_A_ResultRecord(dataStr,"20200200")
                        start_time = self.get_time(0,"000300",is_16=2)
                        try:
                            if end_time[0]=="NULL" and int(begin_time[0])> int(start_time):
                                self.append_step("终端抄表失败事件记录时间正确")
                            else:
                                self.append_step("error：终端抄表失败事件记录时间错误，事件开始时间应大于00:30:00，事件结束时间为NULL",0)
                        except Exception as r:
                            print("%s"%r)
                    else:
                        self.append_step("error：终端抄表失败事件记录数量为{}，错误，应为 1".format(num),0)
                case 3:
                    if num == 1:
                        self.append_step("终端抄表失败事件记录数量为{}，正确".format(num))
                        begin_time,_,_ = Get_Column_Val_From_A_ResultRecord(dataStr,"201E0200")
                        end_time,_,_ = Get_Column_Val_From_A_ResultRecord(dataStr,"20200200")
                        begin_date = self.get_time(0,"003000",is_16 = 2)
                        end_date = self.get_time(0,"004500",is_16 = 2)
                        try:
                            if int(end_time[0])>int(end_date) and int(begin_time[0])> int(begin_date):
                                self.append_step("终端抄表失败事件记录时间正确")
                            else:
                                self.append_step("error：终端抄表失败事件记录时间错误，事件开始时间应大于00:30:00，事件结束时间大于00:45:00",0)
                        except Exception as r:
                            print("%s"%r)
                    else:
                        self.append_step("error：终端抄表失败事件记录数量为{}，错误，应为 1".format(num),0)

        else:
            self.append_step("erro：返回错误码：{} 不合格".format(dar),0)
    def YorN(self, mes = "测试"):
        if self.Is_qualified:
            self.append_step(mes+ " 合格")
        else:
            self.append_step(mes+ " 不合格")
    #最终判定结果是否合格
    def FinalJudg(self,msg):
        if self.Is_qualified:
            self.append_step(msg + " 测试合格")
        else:
            self.append_step(msg + " 测试不合格")
        return
if __name__=="__main__":
    exec_notify=y_esam_no=energy_unit=address = 0
    gen = GeneralProcedure(exec_notify, y_esam_no, energy_unit, address)
    gen.ReadTerminalErrorEventRecord()